#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <unistd.h>

#define SHM_KEY 1234
#define SEM_KEY 5678
#define SHM_SIZE 512

struct shmseg {
    int written;
    char text[SHM_SIZE];
};

// 信号量操作：P操作（等待）
void sem_wait(int semid) {
    struct sembuf sb = {0, -1, 0};
    semop(semid, &sb, 1);
}

// 信号量操作：V操作（释放）
void sem_signal(int semid) {
    struct sembuf sb = {0, 1, 0};
    semop(semid, &sb, 1);
}

int main() {
    int shmid, semid;
    struct shmseg *shm;

    // 创建共享内存
    shmid = shmget(SHM_KEY, sizeof(struct shmseg), 0666 | IPC_CREAT);
    if (shmid == -1) {
        perror("shmget failed");
        exit(1);
    }

    // 创建信号量
    semid = semget(SEM_KEY, 1, 0666 | IPC_CREAT);
    if (semid == -1) {
        perror("semget failed");
        exit(1);
    }

    // 初始化信号量为1
    semctl(semid, 0, SETVAL, 1);

    // 映射共享内存
    shm = (struct shmseg *) shmat(shmid, NULL, 0);
    if (shm == (void *) -1) {
        perror("shmat failed");
        exit(1);
    }

    while (1) {
        sem_wait(semid);
        if (shm->written == 0) {
            printf("Enter message: ");
            fgets(shm->text, SHM_SIZE, stdin);
            shm->written = 1;
        }
        sem_signal(semid);
        sleep(1);
    }

    // 解除映射
if (shmdt(shm) == -1) {
    perror("shmdt failed");
}

// 删除共享内存段
if (shmctl(shmid, IPC_RMID, 0) == -1) {
    perror("shmctl failed");
}

// 删除信号量
if (semctl(semid, 0, IPC_RMID) == -1) {
    perror("semctl failed");
}


    return 0;
}
